﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Grade.cs" company="TomCorp">
//   Thomas Heuberger
// </copyright>
// <summary>
//   Defines the Grade type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace FHIntranetParser {
    using System;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>
    /// The grade.
    /// Implements IEquatable to enable comparisons
    /// </summary>
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
    public class Grade : IEquatable<Grade> {
        /// <summary>
        /// Gets or sets the grd.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        public int Grd { get; set; }

        /// <summary>
        /// Gets or sets the subject.
        /// </summary>
        public string Subject { get; set; }

        /// <summary>
        /// Gets or sets the ects.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        public int Ects { get; set; }

        /// <summary>
        /// Gets or sets the type.
        /// </summary>
        public string Type { get; set; }

        /// <summary>
        /// Gets or sets the date.
        /// </summary>
        public DateTime Date { get; set; }

        /// <summary>
        /// Gets or sets the semester.
        /// </summary>
        public int Semester { get; set; }

        /// <summary>
        /// Function that checks for equality of two grades
        /// </summary>
        /// <param name="other">
        /// The other.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool Equals(Grade other) {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return this.Grd == other.Grd && string.Equals(this.Subject, other.Subject) && this.Ects == other.Ects && string.Equals(this.Type, other.Type) && this.Date.Equals(other.Date) && this.Semester == other.Semester;
        }

        /// <summary>
        /// Function that checks for equality of two grades
        /// </summary>
        /// <param name="obj">
        /// The obj.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        public override bool Equals(object obj) {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return this.Equals((Grade)obj);
        }

        /// <summary>
        /// Override of GetHashCode.
        /// </summary>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public override int GetHashCode() {
            unchecked {
                var hashCode = this.Grd;
                hashCode = (hashCode * 397) ^ this.Subject.GetHashCode();
                hashCode = (hashCode * 397) ^ this.Ects;
                hashCode = (hashCode * 397) ^ this.Type.GetHashCode();
                hashCode = (hashCode * 397) ^ this.Date.GetHashCode();
                hashCode = (hashCode * 397) ^ this.Semester;
                return hashCode;
            }
        }

        /// <summary>
        /// Override of ToString().
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public override string ToString() {
            return string.Format("{0} ({1}): Note: {2}", this.Subject, this.Date.ToShortDateString(), this.Grd);
        }
    }
}
